package com.xxwy.lifecycle.instantiation;

import com.xxwy.lifecycle.bean.User;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.util.ObjectUtils;

/**
 * 4.Bean 实例化生命周期示例.
 * - InstantiationAwareBeanPostProcess
 * 5. Bean 属性赋值
 *   - 前置
 *   - 赋值：赋值后，有一些BeanName这些的回调
 *
 * @author xxwy
 * @date 2021/7/19 0019
 */
public class BeanInstantiationLifeCycleDemo {

    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        // 实例化aware
        beanFactory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
        PropertiesBeanDefinitionReader beanDefinitionReader = new PropertiesBeanDefinitionReader(beanFactory);
        EncodedResource encodedResource = new EncodedResource(new ClassPathResource("META-INF/user.properties"), "UTF-8");
        beanDefinitionReader.loadBeanDefinitions(encodedResource);

        //get Bean
        System.out.println("加载的Bean有：" + beanFactory.getBeanDefinitionCount());
        System.out.println(beanFactory.getBean("user", User.class));
    }

    static class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

        /**
         * 返回非null，则不使用spring ioc的反射生成对象，下面两个回调都不会执行。
         */
        @Override
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            if (ObjectUtils.nullSafeEquals("user", beanName) && User.class.equals(beanClass)) {
                return new User();
            }
            return null;
        }

        /**
         * 返回false, property的赋值不会被执行（下面回调也不会执行）, 这里有bean对象可以随意处理。
         *
         */
        @Override
        public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
            return !ObjectUtils.nullSafeEquals("user", beanName) || !User.class.equals(bean.getClass());
        }

        /**
         * 属性赋值前置方法，
         */
        @Override
        public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
            if (ObjectUtils.nullSafeEquals("user", beanName) && User.class.equals(bean.getClass())) {
                MutablePropertyValues propertyValues = new MutablePropertyValues();
                // <property name="number" value="11" />
                propertyValues.addPropertyValue("number", "11");
                propertyValues.addPropertyValues(pvs);
                return propertyValues;
            }
            return pvs;
        }
    }
}
